package com.bobo.util;

import java.io.File;

/**
 * Maven清理工具类
 *
 * @author LILIBO
 * @since 2023-02-22
 */
public class MavenClearUtil {

    /** 仓库根目录 */
    private static String root = "D:/Source/maven/repository"; // Maven仓库根目录

    public static void main(String[] args) {

        // 清理Maven仓库的空目录依赖（处理下载出错时没有Jar包的情况）
        deleteEmptyVersion(root);

        // 清理Maven仓库的老版本依赖（该操作只保留最新版本，谨慎使用）
        deleteOldVersion(root);
    }

    /**
     * 清理Maven仓库的空目录依赖（下载出错时没有Jar包的情况）
     *
     * @param pathName 仓库文件夹路径
     */
    public static void deleteEmptyVersion(String pathName) {
        File file = new File(pathName);
        File[] fs = file.listFiles();
        if (fs != null && fs.length > 0) {
            for (File f : fs) {
                validateVersion(f);
            }
        }
    }

    /**
     * 验证目录是否为空并删除（没有jar包的目录）
     *
     * @param file
     * @return
     */
    public static boolean validateVersion(File file) {
        boolean isHaveJar = false;
        File[] fs = file.listFiles();
        if (fs != null && fs.length > 0) {
            // 判断是否有*.jar，是否是有文件夹
            for (File f : fs) {
                if (f.getName().endsWith(".jar")) {
                    isHaveJar = true;
                }
                if (f.isDirectory()) {
                    boolean isNextHaveJar = validateVersion(f);
                    if (isNextHaveJar) {
                        isHaveJar = true;
                    }
                }
            }
        }
        if (!isHaveJar) {
            delete(file);
        }
        return isHaveJar;
    }

    /**
     * 清理Maven仓库的老版本依赖（只保留最新版本）
     *
     * @param pathName 仓库文件夹路径
     */
    public static void deleteOldVersion(String pathName) {
        File file = new File(pathName);
        File[] fs = file.listFiles();
        if (fs != null && fs.length > 0) {
            String maxFileName = "0"; // 初始版本号大小
            boolean isVersionBoolean = false; // 判断当前目录下是不是带版本号的文件夹
            for (File f : fs) {
                String dirName = f.getName();
                // 判断子文件夹开头是不是带版本号
                boolean digit = Character.isDigit(dirName.charAt(0));
                Boolean isDirBoolean = f.isDirectory();
                String file0PathString = f.getPath();
                // 是文件夹，开头带版本号
                if (isDirBoolean && digit) {
                    isVersionBoolean = true;
                    try {
                        if (compareVersion(dirName, maxFileName) > 0) {
                            maxFileName = dirName;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else if (isDirBoolean) { // 是普通文件夹就继续循环遍历
                    // 递归遍历文件夹中是否还有文件夹
                    deleteOldVersion(file0PathString);
                }
            }
            if (isVersionBoolean) {
                for (File f : fs) {
                    Boolean isDirBoolean = f.isDirectory();
                    String dirName = f.getName();
                    if (!dirName.equals(maxFileName) && isDirBoolean) {
                        if (f.isDirectory()) {
                            delete(f);
                        }
                        f.delete();
                    }
                }
            }
        } else {
            file.delete();
        }
    }

    /**
     * 比较版本号的大小，前者大则返回一个正数，后者大返回一个负数,相等则返回0 规则是按日期订的例如：2.10.15 项目启动第2年的8月15号
     *
     * @param version1
     * @param version2
     * @return int
     */
    public static int compareVersion(String version1, String version2) throws Exception {
        if (version1 == null || version2 == null) {
            throw new Exception("compareVersion error:illegal params.");
        }
        /* 注意此处为正则匹配，不能用"."； */
        String[] versionArray1 = getVersionArray(version1);
        String[] versionArray2 = getVersionArray(version2);
        int idx = 0;
        /* 取最小长度值 */
        int minLength = Math.min(versionArray1.length, versionArray2.length);
        int diff = 0;
        /* 先比较长度 */
        /* 再比较字符 */
        while (idx < minLength && (diff = versionArray1[idx].length() - versionArray2[idx].length()) == 0
                && (diff = versionArray1[idx].compareTo(versionArray2[idx])) == 0) {
            ++idx;
        }
        /* 如果已经分出大小，则直接返回，如果未分出大小，则再比较位数，有子版本的为大； */
        diff = (diff != 0) ? diff : versionArray1.length - versionArray2.length;
        return diff;
    }

    private static String[] getVersionArray(String ver) {
        String[] versionArray;
        versionArray = ver.split("\\.");
        /* 如果位数只有一位则自动补零（防止出现一个是04，一个是5 直接以长度比较） */
        for (int i = 0; i < versionArray.length; i++) {
            if (versionArray[i].length() == 1) {
                StringBuilder chuShi = new StringBuilder();
                versionArray[i] = chuShi.append("0").append(versionArray[i]).toString();
            }
        }
        return versionArray;
    }

    /**
     * 递归删除目录或子目录中的文件
     *
     * @param file
     */
    public static void delete(File file) {
        File[] _files = file.listFiles();
        if (_files != null && _files.length > 0) {
            for (File _file : _files) {
                if (_file.isDirectory()) {
                    delete(_file);
                }
                System.out.println();
                _file.delete();
            }
        } else {
            file.delete();
        }
    }

}
